package com.suneee.role.service.impl;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.suneee.base.util.ContextHelper;
import com.suneee.context.page.Page;
import com.suneee.core.error.ErrorUtils;
import com.suneee.enterprise.bean.EnterpriseSearchBean;
import com.suneee.enterprise.entity.Enterprise;
import com.suneee.enterprise.service.EnterpriseService;
import com.suneee.orm.util.WhereClauseBuilder;
import com.suneee.permission.bean.PermissionDto;
import com.suneee.permission.dao.PermissionDao;
import com.suneee.permission.entity.Permission;
import com.suneee.permission.utils.PermissionWrapUtil;
import com.suneee.role.bean.RoleDto;
import com.suneee.role.dao.RoleDao;
import com.suneee.role.entity.Role;
import com.suneee.role.service.RoleService;
import com.suneee.role.utils.RoleError;

@Service("api-roleService")
public class RoleServiceImpl implements RoleService {

	private static String PUBLIC_ROLE_ENTERPRISE_FLAG = null;
	private static String PUBLIC_ROLE_NAME = "public_roles";
	private static String PUBLIC_ROLE_CODE = "public_code";
	public static final String PLATFORM_PERMISSION_GROUP = "pt";
	public static final String ENTERPRISE_PERMISSION_GROUP = "en";

	@Autowired
	private RoleDao roleDao;

	@Autowired
	private PermissionDao permissionDao;
	//private PermissionService permissionService;
	
	@Autowired
	private EnterpriseService enterpriseService;

	@Override
	public void add(Role role) {
		// TODO Auto-generated method stub
		role.setCreateTime(new Timestamp(System.currentTimeMillis()));
		role.setLastUpdateTime(new Timestamp(System.currentTimeMillis()));
		role.setEnterpriseCode(ContextHelper.getCurrentLoginInfo()
				.getEnterprise().getEnterpriseCode());
		Boolean status = roleDao.checkExistRole(role);
		if(status)
			throw ErrorUtils.wrap(RoleError.ALREADY_EXIST);
		roleDao.insert(role);
	}

	@Override
	public void authorizedPermission(Integer roleId,
			List<Integer> permissionIdList) {
		// TODO Auto-generated method stub
		roleDao.authorizedPermission(roleId, permissionIdList);
	}

	@Override
	public void delete(Integer roleId) {
		// TODO Auto-generated method stub
		// 获得企业编号
		// String enterpriseCode = "suneee";
		String enterpriseCode = ContextHelper.getCurrentLoginInfo()
				.getEnterprise().getEnterpriseCode();
		List<Map<String, Object>> list = roleDao.checkIsUsed(roleId);
		
		if ((list != null && !list.isEmpty()))
		{
			throw ErrorUtils.wrap(RoleError.DELETE_FAIL, "角色已经被使用，不能删除！");
		}
		
		int result = roleDao.deleteRoleBySQL(roleId, enterpriseCode);
		if (result == 0) 
		{
			throw ErrorUtils.wrap(RoleError.DELETE_FAIL);
		}
	}

	@Override
	public void update(Role role) {
		// TODO Auto-generated method stub
		// 获得企业编号
		// String enterpriseCode = "suneee";
		String enterpriseCode = ContextHelper.getCurrentLoginInfo()
				.getEnterprise().getEnterpriseCode();

		Object[] objs = new Object[2];
		objs[0] = role.getRoleId();
		objs[1] = enterpriseCode;
		List<Role> roles = roleDao.selectWhere(
				" role_id = ? and enterprise_code = ? ", objs);
		if (roles == null || roles.isEmpty()) {
			throw ErrorUtils.wrap(RoleError.NOT_ADMIN);
		}
		Role temp = roles.get(0);
		this.wrap(role, temp);
		roleDao.update(temp);
	}

	/**
	 * 把需要更新的字段写入即将更新的对象
	 * 
	 * @param source
	 * @param target
	 */
	private void wrap(Role source, Role target) {
		if (source.getName() != null) {
			target.setName(source.getName());
		}
		if (source.getEnabled() != null) {
			target.setEnabled(source.getEnabled());
		}
		if (source.getCode() != null) {
			target.setCode(source.getCode());
		}
		target.setLastUpdateTime(new Timestamp(System.currentTimeMillis()));
	}

	@Override
	public void cancelAuthorizedPermission(Integer roleId,
			List<Integer> permissionIdList) {
		// TODO Auto-generated method stub
		roleDao.deleteRelationBySQL(roleId, permissionIdList);
	}

	@Override
	public Page<Role> roleList(RoleDto dto) {
		// TODO Auto-generated method stub
		if (dto == null) {
			dto = new RoleDto();
		}
		dto.setEnterpriseCode(ContextHelper.getCurrentLoginInfo()
				.getEnterprise().getEnterpriseCode());
		return roleDao.roleList(dto);
	}

	@Override
	public Role roleDetail(Integer roleId) {
		// TODO Auto-generated method stub
		Role role = roleDao.roleDetail(roleId, ContextHelper
				.getCurrentLoginInfo().getEnterprise().getEnterpriseCode());
		if (role == null) {
			ErrorUtils.wrap(new Exception("没有权限对此对象操作！"));
		}

		PermissionDto dto = new PermissionDto();
		if (ContextHelper.getCurrentLoginInfo().getEnterprise().getType()
				.equals(Enterprise.SYSTEM)) {// 如果是企业端
			dto.setGroupName(PLATFORM_PERMISSION_GROUP);
		} else {
			dto.setGroupName(ENTERPRISE_PERMISSION_GROUP);
		}
		dto.setEnabled(true);
		List<Permission> list = permissionDao.permissionList(dto);

		List<Permission> temp = role.getPermissionList();
		if (temp != null && !temp.isEmpty()) {
			Map<Integer, Permission> map = new HashMap<>();
			for (Permission permission : list) {
				map.put(permission.getPermissionId(), permission);
			}
			for (Permission permission : temp) {
				Permission pTemp = map.get(permission.getPermissionId());
				if (pTemp != null)
					map.get(permission.getPermissionId()).setSelected(true);
			}
		}

		Map<String, List<Permission>> wrapResult = PermissionWrapUtil
				.treeWrap(list);
		role.setPermissionList(wrapResult.get(PermissionWrapUtil.ROOT_FLAG));
		return role;
	}

	@Override
	@Transactional
	public void permissionModify(Integer roleId, List<Integer> permissionIdList) {
		List<Permission> pList = new ArrayList<Permission>();
		boolean flag = true;
		//循环获取授权的菜单详细信息
		for(Integer param :permissionIdList)
		{
			pList.add(permissionDao.select(param));
		}
		
		//遍历授权菜单列表，判断授权的列表中前端传递的数据是否有漏传一级父类菜单ID
		//（使用场景，对某一角色赋予菜单权限时，选中的第三类子菜单不全选 则前端不会传递该层菜单的一级父类菜单）
		for(Permission p:pList)
		{
			 // 只有在选中三级菜单时才会出现不全选子菜单的情况，前端不会传递一级父类菜单
			if(p.getCode().length() > 4)
			{
				List<Permission> parentList = permissionDao.selectWhere(" code = ? and group_name = 'en' ", p.getCode().substring(0, 2));
				if(null != parentList && parentList.size() > 0)
				{
					int permId = parentList.get(0).getPermissionId();
					
					for(Integer param :permissionIdList)
					{
						if(permId == param)
						{
							flag = false;
						}
					}
					if(flag)
					{
						permissionIdList.add(permId);
					}
				}
			}
			flag = true;
		}
		
		roleDao.deleteRolePermission(roleId);
		this.authorizedPermission(roleId, permissionIdList);
	}

	@Override
	public void addAdminRole(Integer adminId, List<Integer> roleIdList) {
		// TODO Auto-generated method stub
		roleDao.addAdminRole(adminId, roleIdList);
	}

	@Override
	public void cancelAdminRole(Integer adminId, List<Integer> roleIdList) {
		// TODO Auto-generated method stub
		roleDao.cancelAdminRole(adminId, roleIdList);
	}

	@Override
	@Transactional
	public void updateAdminRole(Integer adminId, List<Integer> roleIdList) {
		// TODO Auto-generated method stub
		roleDao.deleteAdminRoleByAdmin(adminId);
		this.addAdminRole(adminId, roleIdList);
	}

	@Override
	public List<Role> adminRoleList(Integer adminId, Boolean flag) {
		// TODO Auto-generated method stub
		return roleDao.adminRoleList(adminId, flag);
	}

	@Override
	@Transactional
	public void addRole(Role role, List<Integer> permissionIdList) {
		// TODO Auto-generated method stub
		role.setCreateTime(new Timestamp(System.currentTimeMillis()));
		role.setLastUpdateTime(new Timestamp(System.currentTimeMillis()));
		role.setEnterpriseCode(ContextHelper.getCurrentLoginInfo()
				.getEnterprise().getEnterpriseCode());
		roleDao.insert(role);
		this.authorizedPermission(role.getRoleId(), permissionIdList);
	}

	@Override
	public List<Role> roleListResult(RoleDto dto) {
		// TODO Auto-generated method stub
		if (dto == null) {
			dto = new RoleDto();
		}
		dto.setEnterpriseCode(ContextHelper.getCurrentLoginInfo()
				.getEnterprise().getEnterpriseCode());
		dto.setEnabled(true);
		return roleDao.roleListResult(dto);
	}

	@Override
	@Transactional
	public List<Role> publicRoles() {
		// TODO Auto-generated method stub
		initialParams();
		List<Role> list = roleDao.publicRoles(PUBLIC_ROLE_NAME,
				PUBLIC_ROLE_ENTERPRISE_FLAG);
		if (list == null || list.isEmpty()) {
			this.addDefaultRole();
			list = roleDao.publicRoles(PUBLIC_ROLE_NAME,
					PUBLIC_ROLE_ENTERPRISE_FLAG);
		}
		return list;
	}

	private void initialParams() {
		if (PUBLIC_ROLE_ENTERPRISE_FLAG == null) {
			EnterpriseSearchBean bean = new EnterpriseSearchBean();
			bean.setType(Enterprise.SYSTEM);
			Page<Enterprise> page = enterpriseService.find(bean);
			if (page == null || page.getItems() == null
					|| page.getItems().isEmpty()) {
				ErrorUtils.wrap(new Exception("尚未添加平台企业，请联系客服！"));
			}
			PUBLIC_ROLE_ENTERPRISE_FLAG = page.getItems().get(0)
					.getEnterpriseCode();
		}
	}

	/**
	 * 添加默认角色
	 */
	@Transactional
	private void addDefaultRole() {
		Role role = new Role();
		role.setName(PUBLIC_ROLE_NAME);
		role.setEnterpriseCode(PUBLIC_ROLE_ENTERPRISE_FLAG);
		role.setEnabled(true);
		role.setCode(PUBLIC_ROLE_CODE);
		role.setCreateTime(new Timestamp(System.currentTimeMillis()));
		role.setLastUpdateTime(new Timestamp(System.currentTimeMillis()));
		roleDao.insert(role);

		PermissionDto dto = new PermissionDto();
		dto.setGroupName(PLATFORM_PERMISSION_GROUP);
		List<Permission> permissionList = permissionDao.permissionList(dto);
		if (permissionList != null && !permissionList.isEmpty()) {
			List<Integer> permissionIdList = new ArrayList<>();
			for (Permission permission : permissionList) {
				permissionIdList.add(permission.getPermissionId());
			}
			this.authorizedPermission(role.getRoleId(), permissionIdList);
		}
	}
}
